import { FrameInfo, PlayerInfo, RecvFrameMessage, RecvFromServerInfo } from "../../GOBE/GOBE";
import PlayeItem from "../Common/PlayeItem";
import { SceneType } from "../CommonValue";
import GameUtils from "../GameUtils";
import { CmdType } from "../GameValue";
import { Global } from "../Global";
import NetSender from "../NetWork/NetSender";

const { ccclass, property } = cc._decorator;

@ccclass
export default class Game extends cc.Component {

    @property(cc.Label)
    gameIdLabel: cc.Label = null;

    @property(cc.Label)
    gameStateLabel: cc.Label = null;

    @property([cc.Node])
    ndPlayers: cc.Node[] = [];
    private playersCtrl: PlayeItem[] = [];

    @property([cc.Button])
    btnCoins: cc.Button[] = [];

    protected start(): void {
        // if (Global.Inst().room.ownerId == Global.Inst().playerId) {
        //     Global.Inst().room.stopFrameSync().then(() => {
        //         // 开始帧同步成功
        //         GameUtils.Log("关闭帧同步成功");
        //     }).catch((e) => {
        //         // 开始帧同步失败
        //         console.error("提示", "关闭帧同步失败", e);
        //     });
        // }

        this.initView();
        this.initListener();
    }
    protected update(dt: number): void {
        const roomInfo = Global.Inst().roomInfo;
        if (!roomInfo || !roomInfo.endTime) return;
        let time = Math.round((roomInfo.endTime - Date.now()) / 1000);
        this.gameStateLabel.string = `环节: ${roomInfo.type} -${roomInfo.stepIndex}剩余时间: ${time} 秒`;
    }


    initView() {
        const room = Global.Inst().room;
        // 设置文本标签
        this.gameIdLabel.string = "房间号：" + room.roomCode;
        for (let index = 0; index < this.ndPlayers.length; index++) {
            const element = this.ndPlayers[index];
            this.playersCtrl.push(element.children[0].getComponent(PlayeItem));
        }


        // 帧同步
        // this.frameSyncView.onUpButtonClick = () => this.sendPlaneFlyFrame(Direction.up);
        // this.frameSyncView.onDownButtonClick = () => this.sendPlaneFlyFrame(Direction.down);
        // this.frameSyncView.onLeftButtonClick = () => this.sendPlaneFlyFrame(Direction.left);
        // this.frameSyncView.onRightButtonClick = () => this.sendPlaneFlyFrame(Direction.right);
        // this.frameSyncView.onStopFrameButtonClick = () => this.stopGame();
        // this.frameSyncView.onFireButtonClick = () => this.sendBulletFlyFrame();
        // this.frameSyncView.onLeaveButtonClick = () => this.watcherLeaveRoom();
        // this.frameSyncView.setButtons(global.gameSceneType, global.playerId === global.room.ownerId);
        // // 设置dialog
        // const dialogNode = cc.instantiate(this.dialogPrefab) as cc.Node;
        // dialogNode.parent = this.node;
        // // 设置加载Dialog
        // const reloadingNode = cc.instantiate(this.reloadingPrefab) as cc.Node;
        // reloadingNode.parent = this.node;
    }
    initListener() {
        // 监听房间
        if (Global.Inst().room) {
            //监听帧数据广播
            // Global.Inst().room.onRecvFrame((frame) => this.onReceiveFrame(frame));
            Global.Inst().room.onRecvFromServer(this.onReceiveFromServer.bind(this));
            // global.room.onStopFrameSync(() => this.onStopFrameSync());
            Global.Inst().room.onDismiss(this.onDismiss.bind(this));
            Global.Inst().room.onLeave(this.onLeave.bind(this));
            // 上线通知监听
            Global.Inst().room.onConnect(this.onConnect.bind(this));
            // // 断线通知监听
            Global.Inst().room.onDisconnect(this.onDisconnect.bind(this));
            Global.Inst().room.onJoin(this.onJoin.bind(this)); // 进行补帧
            // global.room.onRequestFrameError((err) => this.onRequestFrameError(err));// 补帧失败回调

        }
    }




    setRoomView() {
        const room = Global.Inst().room;
        const roomInfo = Global.Inst().roomInfo.playerArr;
        // 设置文本标签
        this.gameIdLabel.string = "房间号：" + room.roomId;
        let index = 0;
        for (const element of this.playersCtrl) {
            element.setReadyStatusByString("");
            element.isOwner(false);
            element.setName("无");
            if (!roomInfo[index]) continue;

            if (Global.Inst().playerId == roomInfo[index].playerId) {
                element.setName("我" + roomInfo[index].playerId.slice(-4));
            } else {
                element.setName("对手" + roomInfo[index].playerId.slice(-4));
            }
            element.setReadyStatusByString("金币：" + roomInfo[index].coin + "");
            element.isOwner(roomInfo[index].playerId == room.ownerId);
            index++;
        }




        // // 房间人数变化，重新计算帧
        // if (roomInfo.players.length !== frameSyncPlayerList.players.length) {
        //     this.frameSyncView.reCalcFrameState();
        // }
    }


    // 接收帧广播消息
    onReceiveFrame(frame: RecvFrameMessage | RecvFrameMessage[]) {
        // 本次接收帧存入“未处理帧”数组中,只负责接收,不处理数据

        console.error("帧广播:", frame)
        Global.Inst().unhandleFrames = Global.Inst().unhandleFrames.concat(frame);
    }

    // 接收实时服务器消息
    onReceiveFromServer(serverInfo: RecvFromServerInfo) {

        Global.Inst().unProcessedServerInfo = Global.Inst().unProcessedServerInfo.concat(serverInfo);
        if (serverInfo.msg) {
            let parseMsg = JSON.parse(serverInfo.msg);
            switch (parseMsg.type) {
                case "RoomInfo":
                    console.error("实时服务器消息:", JSON.parse(parseMsg.data))
                    Global.Inst().roomInfo = JSON.parse(parseMsg.data);
                    this.setRoomView();
                    break;
                case "Pk":
                    console.error("实时服务器消息:", JSON.parse(parseMsg.data))
                    this.setCoinBtnEnable(true, JSON.parse(parseMsg.data).coinData);
                    Global.Inst().roomInfo = JSON.parse(parseMsg.data);
                    this.doResertAni();
                    this.setRoomView();
                    break;

                case "PKResult":
                    console.error("实时服务器消息:", JSON.parse(parseMsg.data));
                    Global.Inst().roomInfo = JSON.parse(parseMsg.data);
                    this.doPKAni();
                    break;

                default:
                    console.error("实时服务器消息:", JSON.parse(parseMsg.data))
                    break;
            }
        }
    }

    setCoinBtnEnable(enable: boolean, coins: number[] = []) {
        for (let index = 0; index < this.btnCoins.length; index++) {
            const element = this.btnCoins[index];
            element.interactable = enable;
            if (coins[index] === undefined) {
                element.node.active = false;
            } else {
                element.node.active = true;
                element.getComponentInChildren(cc.Label).string = "金币:" + coins[index] + "";
            }
        }
    }

    doPKAni() {
        let pkResult = Global.Inst().roomInfo.pkResult;
        for (const [key, element] of Object.entries(pkResult || {})) {
            for (let index = 0; index < element.length; index++) {
                const playerId = element[index];
                const playerIndex = Global.Inst().roomInfo.playerArr.find(p => p.playerId === playerId)?.seatIndex;
                if (playerIndex === undefined) continue;
                const ndPlayer = this.ndPlayers[playerIndex].children[0];
                if (ndPlayer) {
                    ndPlayer.stopAllActions();
                    ndPlayer.runAction(cc.repeatForever(cc.sequence(cc.moveBy(0.5, 0, 10), cc.moveBy(0.5, 0, -10))));
                }
                const ndCoin = this.btnCoins[Number(key)];
                if (ndCoin) {
                    let posEnd = ndCoin.node.convertToWorldSpaceAR(cc.v2(0, 0));
                    ndPlayer?.runAction(cc.jumpTo(1, ndPlayer.parent.convertToNodeSpaceAR(posEnd), 100, 1));
                }
            }
        }

    }

    doResertAni() {
        for (let index = 0; index < this.ndPlayers.length; index++) {
            const ndPlayer = this.ndPlayers[index].children[0];
            ndPlayer.stopAllActions();
            ndPlayer.position = cc.v3(0, 0, 0);
            if (ndPlayer) {
                ndPlayer.runAction(cc.repeatForever(cc.sequence(cc.moveBy(0.5, 0, 10), cc.moveBy(0.5, 0, -10))));
            }

        }

    }


    onConnect(playerInfo: PlayerInfo) {
        if (playerInfo.playerId === Global.Inst().playerId) {
            Global.Inst().isConnected = true;
            GameUtils.Log("玩家在线了");
        } else {
            GameUtils.Log("房间内其他玩家上线了，playerId:" + playerInfo.playerId);
        }
    }
    onJoin(playerInfo: PlayerInfo) {
        GameUtils.Log("重连成功" + playerInfo.playerId);
        if (playerInfo.playerId === Global.Inst().playerId) {
            // global.room.update().then((room) => {
            //     let isInRoom = this.isInRoom(room);
            //     if (isInRoom) {
            //         Reloading.close();
            //     } else {
            //         global.gameSceneType = GameSceneType.FOR_NULL;
            //         cc.director.loadScene("hall");
            //     }
            // }).catch((e) => {
            //     GameUtils.Log("update err: " + e);
            //     cc.director.loadScene("hall");
            // });
        }
    }

    onDisconnect(playerInfo: PlayerInfo) {
        GameUtils.Log("玩家掉线" + playerInfo.playerId);
        if (playerInfo.playerId === Global.Inst().playerId) {
            Global.Inst().isConnected = false;
            // Reloading.open("正在重连。。。", false);
            // this.reConnect();
        }
    }

    onDismiss() {
        GameUtils.Log("SDK广播--解散房间");
        // global.gameSceneType = GameSceneType.FOR_NULL;
        cc.director.loadScene("hall");
    }

    onLeave(playerInfo: PlayerInfo) {
        GameUtils.Log("SDK广播--离开房间" + playerInfo.playerId);
        if (global.isTeamMode) {
            // 重新计算房间内的人员信息
            // this.reCalPlayers(playerInfo);
        } else {
            cc.director.loadScene("room");
        }
    }


    /////////////////////按钮/////////////
    // 房主上报各个玩家起始位置信息
    OnReportInitRoomBtnClick() {
        // 如果是房主，上报公共参数以及所有玩家初始位置
        if (Global.Inst().playerId == Global.Inst().room.ownerId) {
            NetSender.SendInitRoom();
        } else {
            GameUtils.Log("只有房主才能初始化房间信息");
        }
    }

    OnStartGameBtnClick() {
        NetSender.SendStartRoom();
    }

    OnSlickBtnClick(data: cc.Event.EventTouch, index: number) {
        NetSender.SendSlickBox(index);
    }

}
